package com.adjaisd.scarecrow.controller;

import com.adjaisd.scarecrow.common.result.Result;
import com.adjaisd.scarecrow.common.utils.jwt.JwtUtils;
import com.adjaisd.scarecrow.entity.Device;
import com.adjaisd.scarecrow.service.DeviceService;
import com.adjaisd.scarecrow.service.QuotaService;
import com.adjaisd.scarecrow.service.RedisService;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author adjaisd
 * @since 2022-03-10
 */
@RestController
@RequestMapping("/device")
public class DeviceController {

    @Autowired
    DeviceService deviceService;

    @ApiOperation(value = "查询设备")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Result getDeviceList(HttpServletRequest request) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        List<Device> devices = deviceService.getDeviceListByUID(userId);
        return Result.succ().code(200)
                .data("devices", devices)
                .message("查询成功");
    }

    @ApiOperation(value = "添加设备")
    @ApiImplicitParam(name = "deviceForm", required = true, value = "设备信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Result addDevice(HttpServletRequest request, @RequestBody Map<String, String> deviceForm) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        try {
            long number = Long.parseLong(deviceForm.get("number"));
            String name = deviceForm.get("name");
            String desc = deviceForm.get("desc");
            long time = new Date().getTime();
            Device device = new Device(null, number, name, desc, time, "", userId);

            Device d = deviceService.getDeviceByNumber(number);
            if (d != null) {
                if (d.getBindTime() != 0L)
                    return Result.fail().code(50015).message("设备已经绑定");
                device.setId(d.getId());
                deviceService.updateById(device);
            } else {
                deviceService.addDevice(device);
                Device t = deviceService.getDeviceByNumberUID(number, userId);
                device.setId(t.getId());
            }
            return Result.succ().code(200).data("device", device).message("添加设备成功");
        } catch (Exception e) {
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    @Autowired
    QuotaService quotaService;

    @ApiOperation(value = "删除设备")
    @ApiImplicitParam(name = "deviceForm", required = true, value = "设备信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Result delDevice(HttpServletRequest request, @RequestBody Map<String, String> deviceForm) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        try {
            long number = Long.parseLong(deviceForm.get("number"));

            Device device = deviceService.getDeviceByNumberUID(number, userId);
            if (device != null) {
                if (device.getBindTime() == 0L)
                    return Result.fail().code(50015).message("不存在该设备");

                // 检测设备下是否存在指标
                if (quotaService.existQuotaByNumberUID(device.getNumber(), userId))
                    return Result.fail().code(401).message("设备下存在指标");

                if (deviceService.delDevice(userId, number)) return Result.succ().code(200).message("删除设备成功");
                else return Result.fail().code(500).message("删除失败");
            } else return Result.fail().code(50015).message("不存在该设备");
        } catch (Exception e) {
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    @ApiOperation(value = "更新设备")
    @ApiImplicitParam(name = "deviceForm", required = true, value = "设备信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Result updateDevice(HttpServletRequest request, @RequestBody Map<String, String> deviceForm) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        try {
            // 不可变
            long number = Long.parseLong(deviceForm.get("number"));

            // 可变
            String name = deviceForm.get("name");
            String desc = deviceForm.get("desc");
            String icon = deviceForm.get("icon");

            Device device = deviceService.getDeviceByNumberUID(number, userId);
            if (device != null) {
                if (device.getBindTime() == 0L)
                    return Result.fail().code(50015).message("不存在该设备");
                device.setName(name);
                device.setDescription(desc);
                device.setIcon(icon);
                if (deviceService.updateById(device))
                    return Result.succ().code(200).message("更新设备信息成功");
                else
                    return Result.fail().code(500).message("更新失败");
            } else return Result.fail().code(50015).message("不存在该设备");
        } catch (Exception e) {
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    @Autowired
    RedisService redisService;

    // 请求设备配网token: get: /device/token
    @ApiOperation(value = "请求设备配网token")
    @RequestMapping(value = "/token", method = RequestMethod.POST)
    @ResponseBody
    public Result getDeviceTokenWithAuth(HttpServletRequest request, @RequestBody Map<String, String> form) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        try {
            long number = Long.parseLong(form.get("number"));

            Device device = deviceService.getDeviceByNumberUID(number, userId);
            if (device != null) {
                if (device.getBindTime() == 0L)
                    return Result.fail().code(50017).message("不存在该设备");
                else {
                    String deviceToken = JwtUtils.getJwtToken(device.getId(),
                            device.getName(), "" + number, "666");
                    String deviceKey = "device" + device.getId();
                    redisService.set(deviceKey, deviceToken, 60);
                    return Result.succ().code(200)
                            .data("deviceName", device.getName())
                            .data("deviceToken", deviceToken)
                            .message("获取设备token成功");
                }
            } else return Result.fail().code(50017).message("不存在该设备");
        } catch (Exception e) {
            return Result.fail().code(50017).message("缺少必要参数");
        }
    }

    // -------测试用----------------

    @ApiOperation(value = "请求设备配网token")
    @RequestMapping(value = "/notoken", method = RequestMethod.POST)
    @ResponseBody
    public Result getDeviceTokenWithoutAuth(HttpServletRequest request, @RequestBody Map<String, String> form) {
        try {
            long number = Long.parseLong(form.get("number"));
            Device device = deviceService.getDeviceByNumber(number);
            if (device == null || device.getBindTime() == 0L)
                return Result.fail().code(50017).message("不存在该设备");
            else {
                String deviceToken = JwtUtils.getJwtToken(device.getId(),
                        device.getName(), "" + number, "666");
                String deviceKey = "device" + device.getId();
                redisService.set(deviceKey, deviceToken, 60);
                return Result.succ().code(200)
                        .data("deviceName", device.getName())
                        .data("deviceToken", deviceToken)
                        .message("获取设备token成功");
            }
        } catch (Exception e) {
            return Result.fail().code(50017).message("缺少必要参数");
        }
    }
}
